package net.shopxx.boot;

import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.env.Environment;

import com.google.code.kaptcha.impl.DefaultKaptcha;

import freemarker.template.TemplateModelException;
import net.shopxx.captcha.CaptchaFilter;
import net.shopxx.template.directive.AdPositionDirective;
import net.shopxx.template.directive.ArticleCategoryChildrenListDirective;
import net.shopxx.template.directive.ArticleCategoryParentListDirective;
import net.shopxx.template.directive.ArticleCategoryRootListDirective;
import net.shopxx.template.directive.ArticleListDirective;
import net.shopxx.template.directive.ArticleTagListDirective;
import net.shopxx.template.directive.AttributeListDirective;
import net.shopxx.template.directive.BrandListDirective;
import net.shopxx.template.directive.BusinessAttributeListDirective;
import net.shopxx.template.directive.BusinessCashCountDirective;
import net.shopxx.template.directive.CategoryApplicationCountDirective;
import net.shopxx.template.directive.ConsultationListDirective;
import net.shopxx.template.directive.DistributionCashCountDirective;
import net.shopxx.template.directive.FriendLinkListDirective;
import net.shopxx.template.directive.HasAnyPermissionsTagDirective;
import net.shopxx.template.directive.HasPermissionTagDirective;
import net.shopxx.template.directive.InstantMessageListDirective;
import net.shopxx.template.directive.MemberAttributeListDirective;
import net.shopxx.template.directive.NavigationListDirective;
import net.shopxx.template.directive.OrderCountDirective;
import net.shopxx.template.directive.PaginationDirective;
import net.shopxx.template.directive.ProductCategoryChildrenListDirective;
import net.shopxx.template.directive.ProductCategoryParentListDirective;
import net.shopxx.template.directive.ProductCategoryRootListDirective;
import net.shopxx.template.directive.ProductCountDirective;
import net.shopxx.template.directive.ProductFavoriteDirective;
import net.shopxx.template.directive.ProductListDirective;
import net.shopxx.template.directive.ProductTagListDirective;
import net.shopxx.template.directive.PromotionListDirective;
import net.shopxx.template.directive.PromotionPluginDirective;
import net.shopxx.template.directive.ReviewCountDirective;
import net.shopxx.template.directive.ReviewListDirective;
import net.shopxx.template.directive.SeoDirective;
import net.shopxx.template.directive.StoreAdImageListDirective;
import net.shopxx.template.directive.StoreCountDirective;
import net.shopxx.template.directive.StoreFavoriteDirective;
import net.shopxx.template.directive.StoreProductCategoryChildrenListDirective;
import net.shopxx.template.directive.StoreProductCategoryParentListDirective;
import net.shopxx.template.directive.StoreProductCategoryRootListDirective;
import net.shopxx.template.directive.StoreProductTagDirective;
import net.shopxx.template.method.AbbreviateMethod;
import net.shopxx.template.method.CurrencyMethod;
import net.shopxx.template.method.MessageMethod;

@Configuration
public class FreemarkerConfig {

    @Autowired
    private Environment env;
    
    @Autowired
    private freemarker.template.Configuration configuration;
    @Autowired
    private MessageMethod messageMethod;
    @Autowired
    private AbbreviateMethod abbreviateMethod;
    @Autowired
    private CurrencyMethod currencyMethod;
    @Autowired
    private AdPositionDirective adPositionDirective;
    @Autowired
    private ArticleCategoryChildrenListDirective articleCategoryChildrenListDirective;
    @Autowired
    private ArticleCategoryParentListDirective articleCategoryParentListDirective;
    @Autowired
    private ArticleCategoryRootListDirective articleCategoryRootListDirective;
    @Autowired
    private ArticleListDirective articleListDirective;
    @Autowired
    private ArticleTagListDirective articleTagListDirective;
    @Autowired
    private AttributeListDirective attributeListDirective;
    @Autowired
    private BrandListDirective brandListDirective;
    @Autowired
    private BusinessAttributeListDirective businessAttributeListDirective;
    @Autowired
    private BusinessCashCountDirective businessCashCountDirective;
    @Autowired
    private CategoryApplicationCountDirective categoryApplicationCountDirective;
    @Autowired
    private ConsultationListDirective consultationListDirective;
    @Autowired
    private DistributionCashCountDirective distributionCashCountDirective;
    @Autowired
    private FriendLinkListDirective friendLinkListDirective;
    @Autowired
    private InstantMessageListDirective instantMessageListDirective;
    @Autowired
    private MemberAttributeListDirective memberAttributeListDirective;
    @Autowired
    private NavigationListDirective navigationListDirective;
    @Autowired
    private OrderCountDirective orderCountDirective;
    @Autowired
    private PaginationDirective paginationDirective;
    @Autowired
    private ProductCategoryChildrenListDirective productCategoryChildrenListDirective;
    @Autowired
    private ProductCategoryParentListDirective productCategoryParentListDirective;
    @Autowired
    private ProductCategoryRootListDirective productCategoryRootListDirective;
    @Autowired
    private ProductCountDirective productCountDirective;
    @Autowired
    private ProductFavoriteDirective productFavoriteDirective;
    @Autowired
    private ProductListDirective productListDirective;
    @Autowired
    private ProductTagListDirective productTagListDirective;
    @Autowired
    private PromotionListDirective promotionListDirective;
    @Autowired
    private PromotionPluginDirective promotionPluginDirective;
    @Autowired
    private ReviewCountDirective reviewCountDirective;
    @Autowired
    private ReviewListDirective reviewListDirective;
    @Autowired
    private SeoDirective seoDirective;
    @Autowired
    private StoreAdImageListDirective storeAdImageListDirective;
    @Autowired
    private StoreCountDirective storeCountDirective;
    @Autowired
    private StoreFavoriteDirective storeFavoriteDirective;
    @Autowired
    private StoreProductCategoryChildrenListDirective storeProductCategoryChildrenListDirective;
    @Autowired
    private StoreProductCategoryParentListDirective storeProductCategoryParentListDirective;
    @Autowired
    private StoreProductCategoryRootListDirective storeProductCategoryRootListDirective;
    @Autowired
    private StoreProductTagDirective storeProductTagDirective;
    @Autowired
    private HasPermissionTagDirective hasPermissionTagDirective;
    @Autowired
    private HasAnyPermissionsTagDirective hasAnyPermissionsTagDirective;
    @Autowired
    private ServletContext servletContext;
    
    @Bean
    public DefaultKaptcha captchaProducer(){
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        final Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "no");
        properties.setProperty("kaptcha.image.width", env.getProperty("captcha.imageWidth"));
        properties.setProperty("kaptcha.image.height", env.getProperty("captcha.imageHeight"));
        properties.setProperty("kaptcha.textproducer.char.string", env.getProperty("captcha.charString"));
        properties.setProperty("kaptcha.textproducer.char.length", env.getProperty("captcha.charLength"));
        properties.setProperty("kaptcha.textproducer.char.space", env.getProperty("captcha.charSpace"));
        properties.setProperty("kaptcha.textproducer.font.color", env.getProperty("captcha.fontColor"));
        properties.setProperty("kaptcha.textproducer.font.size", env.getProperty("captcha.fontSize"));
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");
        properties.setProperty("kaptcha.background.impl", "net.shopxx.captcha.CaptchaBackground");
        properties.setProperty("kaptcha.background.imagePath", servletContext.getRealPath("/")+env.getProperty("captcha.background_image_path"));
        com.google.code.kaptcha.util.Config config = new com.google.code.kaptcha.util.Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
    
    @Bean
    @Scope("prototype")
    public CaptchaFilter captchaFilter(){
        CaptchaFilter captchaFilter = new CaptchaFilter();
        return captchaFilter;
    }
    
    @PostConstruct
    public void setSharedVariable() throws TemplateModelException{
        configuration.setSharedVariable("base", servletContext.getContextPath());
        configuration.setSharedVariable("showPowered", env.getProperty("show_powered"));
        configuration.setSharedVariable("message", messageMethod);
        configuration.setSharedVariable("abbreviate", abbreviateMethod);
        configuration.setSharedVariable("currency", currencyMethod);
        configuration.setSharedVariable("ad_position", adPositionDirective);
        configuration.setSharedVariable("article_category_children_list", articleCategoryChildrenListDirective);
        configuration.setSharedVariable("article_category_parent_list", articleCategoryParentListDirective);
        configuration.setSharedVariable("article_category_root_list", articleCategoryRootListDirective);
        configuration.setSharedVariable("article_list", articleListDirective);
        configuration.setSharedVariable("article_tag_list", articleTagListDirective);
        configuration.setSharedVariable("attribute_list", attributeListDirective);
        configuration.setSharedVariable("brand_list", brandListDirective);
        configuration.setSharedVariable("business_attribute_list", businessAttributeListDirective);
        configuration.setSharedVariable("business_cash_count", businessCashCountDirective);
        configuration.setSharedVariable("category_application_count", categoryApplicationCountDirective);
        configuration.setSharedVariable("consultation_list", consultationListDirective);
        configuration.setSharedVariable("distribution_cash_count", distributionCashCountDirective);
        configuration.setSharedVariable("friend_link_list", friendLinkListDirective);
        configuration.setSharedVariable("instant_message_list", instantMessageListDirective);
        configuration.setSharedVariable("member_attribute_list", memberAttributeListDirective);
        configuration.setSharedVariable("navigation_list", navigationListDirective);
        configuration.setSharedVariable("order_count", orderCountDirective);
        configuration.setSharedVariable("pagination", paginationDirective);
        configuration.setSharedVariable("product_category_children_list", productCategoryChildrenListDirective);
        configuration.setSharedVariable("product_category_parent_list", productCategoryParentListDirective);
        configuration.setSharedVariable("product_category_root_list", productCategoryRootListDirective);
        configuration.setSharedVariable("product_count", productCountDirective);
        configuration.setSharedVariable("product_favorite", productFavoriteDirective);
        configuration.setSharedVariable("product_list", productListDirective);
        configuration.setSharedVariable("product_tag_list", productTagListDirective);
        configuration.setSharedVariable("promotion_list", promotionListDirective);
        configuration.setSharedVariable("promotion_plugin", promotionPluginDirective);
        configuration.setSharedVariable("review_count", reviewCountDirective);
        configuration.setSharedVariable("review_list", reviewListDirective);
        configuration.setSharedVariable("seo", seoDirective);
        configuration.setSharedVariable("store_ad_image_list", storeAdImageListDirective);
        configuration.setSharedVariable("store_count", storeCountDirective);
        configuration.setSharedVariable("store_favorite", storeFavoriteDirective);
        configuration.setSharedVariable("store_product_category_children_list", storeProductCategoryChildrenListDirective);
        configuration.setSharedVariable("store_product_category_parent_list", storeProductCategoryParentListDirective);
        configuration.setSharedVariable("store_product_category_root_list", storeProductCategoryRootListDirective);
        configuration.setSharedVariable("store_product_tag_list", storeProductTagDirective);
        configuration.setSharedVariable("has_permission_tag", hasPermissionTagDirective);
        configuration.setSharedVariable("has_any_permissions_tag", hasAnyPermissionsTagDirective);
    }
}
